package com.steven.team.config;

import com.alibaba.fastjson.JSONObject;
import com.steven.team.dao.ChatDao;
import com.steven.team.dao.FriendDao;
import com.steven.team.dao.TeamDao;
import com.steven.team.pojo.Friend;
import com.steven.team.service.ChatService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Component
public class SpringWebSocketHandler extends TextWebSocketHandler {

    private static Logger logger = LoggerFactory.getLogger(SpringWebSocketHandler.class);

    private static final Map<String, WebSocketSession> users;  //Map来存储WebSocketSession，key用USER_ID 即在线用户列表

    //用户标识
    private static final String USER_ID = "uid";   //对应监听器从的key
    private volatile static SpringWebSocketHandler instance;

    @Autowired
    private ChatDao chatDao;
    @Autowired
    private FriendDao friendDao;
    @Autowired
    private TeamDao teamDao;

    static {
        users = new HashMap<String, WebSocketSession>();
    }

    private SpringWebSocketHandler() {
    }

    public static SpringWebSocketHandler getInstance() {
        if (instance == null) {
            instance = new SpringWebSocketHandler();
        }
        return instance;
    }

    /**
     * 连接成功时候，会触发页面上onopen方法
     */
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String userId = (String) session.getAttributes().get(USER_ID);
        users.put(userId, session);
        System.out.println("成功建立websocket连接!\n" + userId + "已上线");
        System.out.println("当前线上用户数量:" + users.size());
        TextMessage returnMessage;
        JSONObject json = new JSONObject();

        json.put("type", "OffLineMessage");
        json.put("data", chatDao.queryAllUnreadMessage(Long.parseLong(userId)));
        returnMessage = new TextMessage(json.toString());
        System.out.println(json.toString());
        session.sendMessage(returnMessage);

        json.clear();
        json.put("type", "Apply");
        json.put("data", friendDao.queryApplicationToSelfUnRead(Long.parseLong(userId)));
        returnMessage = new TextMessage(json.toString());
        System.out.println(json.toString());
        session.sendMessage(returnMessage);

        json.clear();
        json.put("type", "Account");
        json.put("data", teamDao.selectUserBanByUid(Long.parseLong(userId)).size() > 0);
        returnMessage = new TextMessage(json.toString());
        System.out.println(json.toString());
        session.sendMessage(returnMessage);
    }

    /**
     * 关闭连接时触发
     */
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        logger.debug("关闭websocket连接");
        String userId = (String) session.getAttributes().get(USER_ID);
        System.out.println("用户" + userId + "已退出！");
        users.remove(userId);
        System.out.println("剩余在线用户" + users.size());
    }

    /**
     * js调用websocket.send时候，会调用该方法
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

        super.handleTextMessage(session, message);

        /**
         * 收到消息，自定义处理机制，实现业务
         */
        System.out.println("服务器收到消息：" + message);

        if (message.getPayload().startsWith("#anyone#")) { //单发某人

            sendMessageToUser((String) session.getAttributes().get(USER_ID), new TextMessage("服务器单发：" + message.getPayload()));

        } else if (message.getPayload().startsWith("#everyone#")) {

            sendMessageToUsers(new TextMessage("服务器群发：" + message.getPayload()));

        } else {

        }

    }

    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if (session.isOpen()) {
            session.close();
        }
        logger.debug("传输出现异常，关闭websocket连接... ");
        String userId = (String) session.getAttributes().get(USER_ID);
        users.remove(userId);
    }

    public boolean supportsPartialMessages() {

        return false;
    }


    /**
     * 给某个用户发送消息
     *
     * @param userId
     * @param message
     */
    public boolean sendMessageToUser(String userId, TextMessage message) {
        try {
            if (users.containsKey(userId)) {
                WebSocketSession session = users.get(userId);
                if (session.isOpen()) {
                    System.out.println(session);
                    session.sendMessage(message);
                    return true;
                }
            }
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 给所有在线用户发送消息
     *
     * @param message
     */
    public boolean sendMessageToUsers(TextMessage message) {
        for (String userId : users.keySet()) {
            try {
                if (users.get(userId).isOpen()) {
                    users.get(userId).sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }
}